/*
 * Scheduler.cpp
 *
 *  Created on: Aug 27, 2011
 *      Author: ryan
 */

#include "Scheduler.h"

void Scheduler::setCPUMapReducer(MapReducer *c){
	cpu = c;
}

void Scheduler::setGPUMapReducer(MapReducer *g){
	gpu = g;
}

void Scheduler::setDevide(double v){
	if(v >= 0 && v <= 1){
		devide = v;
	}
}

void Scheduler::submit(int taskNum, int argc, char *argv[]) {
	Communication::initialize(argc, argv);
	if (Communication::RANK == 0) {
		int num = Communication::SIZE;
		int len = taskNum / num;
		int t = taskNum % num;
		if (t != 0) {
			++len;
		}
		int *task = new int[num];
		for (int k = 0; k < num; ++k) {
			if (k == t && t != 0) {
				--len;
			}
			task[k] = len;
		}
		globalSchduling(task, num);
		delete[] task;
	}
	localSchduling();
}

void Scheduler::globalSchduling(int task[], int num) {
	int start = 0;
	for (int k = 0; k < num; ++k) {
		Communication::sendTo(&k, sizeof(int), k);
		Communication::sendTo(&num, sizeof(int), k);
		Communication::sendTo(&start, sizeof(int), k);
		Communication::sendTo(&task[k], sizeof(int), k);
		start += task[k];
	}
}

void Scheduler::localSchduling() {
	int task_rank, task_total;
	Communication::recvFrom(&task_rank, sizeof(int), 0);
	Communication::recvFrom(&task_total, sizeof(int), 0);
	Communication::recvFrom(&task_start, sizeof(int), 0);
	Communication::recvFrom(&task_length, sizeof(int), 0);
	int len = task_length * devide;
	int *task1 = new int[3];
	task1[0] = task_start;
	task1[1] = len;
	task1[2] = task_rank + 1;
	int rank1 = task_rank;
	KEY_VALUE cpu_in(&rank1, sizeof(int), &task1, 3 * sizeof(int));

	int *task2 = new int[3];
	task2[0] = task_start + len;
	task2[1] = task_length - len;
	if(task_rank < task_total - 1){
		task2[2] =
	}
	int rank2 = task_rank + 1;
	KEY_VALUE gpu_in(&)
	#pragma omp parallel sections
	{
		//cpu part:
		#pragma omp section
		{
			cpu->map();
		}
		//gpu part:
		#pragma omp section
		{
		}
	}
}

MapReducer* Scheduler::cpu = 0;
MapReducer* Scheduler::gpu = 0;
int Scheduler::task_start = 0;
int Scheduler::task_length = 0;
double Scheduler::devide = 0.25;
